#pragma once

#include <AVUIPathSegment.h>

namespace AVUI {

class GeometryBuilder;

class ArcSegment : public PathSegment
{
public:
    DECLARE_ELEMENT(ArcSegment, PathSegment);

    DECLARE_DEPENDENCY_PROPERTY(Point);
    Point get_Point() { return AVUI::UnboxValue<Point>(GetValue(get_PointProperty())); }
    void set_Point(const Point& value) { SetValue(get_PointProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(Size);
    Size get_Size() { return AVUI::UnboxValue<Size>(GetValue(get_SizeProperty())); }
    void set_Size(const Size& value) { SetValue(get_SizeProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(RotationAngle);
    float get_RotationAngle() { return AVUI::UnboxValue<float>(GetValue(get_RotationAngleProperty())); }
    void set_RotationAngle(float value) { SetValue(get_RotationAngleProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(IsLargeArc);
    bool get_IsLargeArc() { return AVUI::UnboxValue<bool>(GetValue(get_IsLargeArcProperty())); }
    void set_IsLargeArc(bool value) { SetValue(get_IsLargeArcProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(SweepDirection);
    SweepDirection::Enum get_SweepDirection() { return (SweepDirection::Enum)(AVUI::UnboxValue<int>(GetValue(get_SweepDirectionProperty()))); }
    void set_SweepDirection(SweepDirection::Enum value) { SetValue(get_SweepDirectionProperty(), AVUI::BoxValue<int>(value)); } 

    static void BuildGeometryStatic(GeometryBuilder* pGeometryBuilder, const Point& startPoint, const Point& endPoint, 
                                    const Size& size, float rotationAngle, bool isLargeArc, SweepDirection::Enum sweepDirection);

    // Center parameterization
    static void BuildGeometryStaticCenter(GeometryBuilder* pGeometryBuilder, const Point& centerPoint,
                                    float radiusX, float radiusY, float angleStart, float angleDest, SweepDirection::Enum sweepDirection);

    virtual bool IsCurved() { return true; };
    virtual bool IsEmpty() { return false; }
    virtual Rect GetBounds(Point* pStartPoint) { return Rect(); }
    virtual int ClassifyPoint(const Point& pointClassify, Point* pStartPoint) { return 0; }

protected:

    virtual TRefCountedPtr<Freezable> CreateInstanceCore() AVUI_OVERRIDE { return object_allocate<ArcSegment>().get_Ptr(); }

private:
    static void StaticConstructor();
    virtual Point BuildGeometry(GeometryBuilder* pGB, const Point& startPoint);
    static TRefCountedPtr<Object> CoerceSize(DependencyObject* pDO, Object* pValue);

};



}; // namespace AVUI
